<template>
    <div>
        <svg width="940" height="500"></svg>
    </div>
</template>
<script>
import * as d3 from 'd3';
export default {
    props:{
        d3Data: Object
    },
    watch:{
        d3Data(){
            // console.log("***** KgRelationMap: ",this.d3Data);
            this.load();
        }
    },
    mounted(){
        this.load();
    },
    methods:{
        drag(simulation){
            function dragstarted(event) {
                if (!event.active) simulation.alphaTarget(0.3).restart();
                event.subject.fx = event.subject.x;
                event.subject.fy = event.subject.y;
            }
            
            function dragged(event) {
                event.subject.fx = event.x;
                event.subject.fy = event.y;
            }
            
            function dragended(event) {
                if (!event.active) simulation.alphaTarget(0);
                event.subject.fx = null;
                event.subject.fy = null;
            }
            
            return d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended);
        },
        color(){
            const scale = d3.scaleOrdinal(d3.schemeCategory10);
            return d => scale(d.group);
        },
        load(){
            // manipulate dom using d3 apis 

            const height = 600;
            const width = 600;
            const svg = d3.select('svg');
            svg.attr("viewBox", [0, 0, width, height]);

            // console.log("***** KgRelationMap: ",JSON.stringify(this.d3Data));

            const links = this.d3Data.links;
            const nodes = this.d3Data.nodes;

            const simulation = d3.forceSimulation(nodes)
                .force("link", d3.forceLink(links).id(d => d.id))
                .force("charge", d3.forceManyBody())
                .force("center", d3.forceCenter(width / 2, height / 2));

            const link = svg.append("g")
                .attr("stroke", "#999")
                .attr("stroke-opacity", 0.6)
                .selectAll("line")
                .data(links)
                .join("line")
                .attr("stroke-width", d => Math.sqrt(d.value));

            const node = svg.append("g")
                .attr("stroke", "#fff")
                .attr("stroke-width", 1.5)
                .selectAll("circle")
                .data(nodes)
                .join("circle")
                .attr("r", 5)
                .attr("fill", this.color())
                .call(this.drag(simulation));

            node.append("title")
                .text(d => d.id);

            simulation.on("tick", () => {
                link
                    .attr("x1", d => d.source.x)
                    .attr("y1", d => d.source.y)
                    .attr("x2", d => d.target.x)
                    .attr("y2", d => d.target.y);

                node
                    .attr("cx", d => d.x)
                    .attr("cy", d => d.y);
            });
        }
    }
};
</script>
<style scoped>

</style>